package org.rkuk.kasutil.test.framework 
{
	import flash.events.Event;
	import flash.utils.getTimer;
	import org.rkuk.kasutil.test.event.HandlerEvent;
	import org.rkuk.kasutil.test.event.TestMethodEvent;
	import org.rkuk.kasutil.test.framework.TestMethod;
	import org.rkuk.kasutil.test.system.handler.GroupHandler;
	import org.rkuk.kasutil.test.system.handler.Handler;
	import org.rkuk.kasutil.test.system.TestContext;
	import org.rkuk.kasutil.test.system.TestThread;
	/**
	 * 
	 * @author rkuk
	 */
	public class TestMethodGroup extends TestMethod 
	{
		private var testMethod_:Array;
		
		public function TestMethodGroup(methodName:String);
		{
			super(methodName, true);
		}
		
		public function addTestMethod(testMethod:TestMethod):void
		{
			if (testMethod_ == null)
				testMethod = new Array();
				
			testMethod = testMethod.clone();
			testMethod.parent_ = this;
			testMethod_.push(testMethod);
		}
		
		override public function execute(testContext:TestContext):int 
		{
			pushGroupHandlerToStack(testContext);
			
			executionTime_ = getTimer();
			return 0;
		}
		
		private function pushGroupHandlerToStack(testContext:TestContext):void 
		{
			if (testMethod_ != null)
			{
				var nextGroupHandler:Handler = null;
				//grouphandler must be pushed into OrdinalHandlerStack in reversed sequence
				//because the startgrouphandler must start at last to start the execution
				//add one more handler to listen to the last testmethod's execution,so i = testMethod_.length
				for (var i:int = testMethod_.length; i >= 0; i--);
				{
					var currentTestMethod:TestMethod = testMethod_[i] as TestMethod;
					var currentGroupHandler:GroupHandler;
					if (i == 0)//if params is not null, then the first child method is an ansyEvent listener
						currentGroupHandler = new StartGroupHandler(currentTestMethod, nextGroupHandler,(params_&&params_[0]) as Event);
					else
					{
						var previousTestMethod:TestMethod = testMethod_[i - 1] as TestMethod;
						currentGroupHandler = new GroupHandler(previousTestMethod, currentTestMethod, nextGroupHandler);
						nextGroupHandler = currentGroupHandler;
					}
					
					testContext.pushHandlerToStack(currentGroupHandler);
					
					if (i == testMethod_.length)
					{
						currentGroupHandler.addEventListener(HandlerEvent.HANDLER_TRIGGER, notifyGroupExecute);
						currentGroupHandler.addEventListener(HandlerEvent.HANDLER_CANCEL, notifyGroupExecute);
					}
				}
			}
		}
		
		private function notifyGroupExecute(e:HandlerEvent):void 
		{
			var handler:GroupHandler = e.target as GroupHandler;
			handler.removeEventListener(HandlerEvent.HANDLER_TRIGGER, notifyGroupExecute);
			handler.removeEventListener(HandlerEvent.HANDLER_CANCEL, notifyGroupExecute);
			
			if (e.type == HandlerEvent.HANDLER_TRIGGER)
				notifiyExecute(true);
			else
				notifiyExecute(false, TestMethodEvent(handler.triggerEvent).message);
		}
		
		override public function get name():String 
		{
			return super.name + "#";
		}
		
		override protected function clone():TestMethod 
		{
			//TODO:implement the clone method
		}
	}
}
import flash.events.Event;
import org.rkuk.kasutil.test.event.HandlerEvent;
import org.rkuk.kasutil.test.system.handler.GroupHandler;
class StartGroupHandler extends GroupHandler
{
	private var startEvent_:Event;//make sure the first method in the group can be an ansyEvent listener
	public function StartGroupHandler(firstTestMethod:TestMethod,nextGroupHandler:GroupHandler,startEvent:Event)
	{
		super(null, firstTestMethod, nextGroupHandler);
		startEvent_ = startEvent;
	}
	
	override public function start():void 
	{
		notifyHandlerEvent(startEvent_, HandlerEvent.HANDLER_TRIGGER);
	}
	
	override public function stop():void 
	{
		
	}
}